﻿using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using Infragistics.Win;
using Infragistics.Win.UltraWinSchedule;
using Infragistics.Win.UltraWinGrid;

namespace TM.Test
{
    /// <summary>
    /// Summary description for Form1.
    /// </summary>
    public partial class Form2 : System.Windows.Forms.Form
    {
        private Infragistics.Win.UltraWinSchedule.UltraCalendarInfo ultraCalendarInfo1;
        private Infragistics.Win.UltraWinSchedule.UltraDayView ultraDayView1;
        private Infragistics.Win.UltraWinSchedule.UltraMonthViewMulti ultraMonthViewMulti1;
        private System.Windows.Forms.Splitter splitter2;
        private System.Windows.Forms.Splitter splitter1;
        private Infragistics.Win.UltraWinGrid.UltraGrid AppointmentGrid;
        private System.Windows.Forms.Splitter splitter3;
        private Infragistics.Win.UltraWinGrid.UltraGrid OwnersGrid;
        private Infragistics.Win.UltraWinGrid.UltraDropDown OwnersDropDown;
        private System.ComponentModel.IContainer components;

        public Form2()
        {
            //
            // Required for Windows Form Designer support
            //
            InitializeComponent();

            //
            // TODO: Add any constructor code after InitializeComponent call
            //
        }

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (components != null)
                {
                    components.Dispose();
                }
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this.ultraCalendarInfo1 = new Infragistics.Win.UltraWinSchedule.UltraCalendarInfo(this.components);
            this.ultraDayView1 = new Infragistics.Win.UltraWinSchedule.UltraDayView();
            this.ultraMonthViewMulti1 = new Infragistics.Win.UltraWinSchedule.UltraMonthViewMulti();
            this.splitter2 = new System.Windows.Forms.Splitter();
            this.AppointmentGrid = new Infragistics.Win.UltraWinGrid.UltraGrid();
            this.splitter1 = new System.Windows.Forms.Splitter();
            this.splitter3 = new System.Windows.Forms.Splitter();
            this.OwnersGrid = new Infragistics.Win.UltraWinGrid.UltraGrid();
            this.OwnersDropDown = new Infragistics.Win.UltraWinGrid.UltraDropDown();
            ((System.ComponentModel.ISupportInitialize)(this.ultraDayView1)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.ultraMonthViewMulti1)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.AppointmentGrid)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.OwnersGrid)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.OwnersDropDown)).BeginInit();
            this.SuspendLayout();
            // 
            // ultraCalendarInfo1
            // 
            this.ultraCalendarInfo1.AfterSelectedAppointmentsChange += new System.EventHandler(this.ultraCalendarInfo1_AfterSelectedAppointmentsChange);
            this.ultraCalendarInfo1.AppointmentDataInitialized += new Infragistics.Win.UltraWinSchedule.AppointmentDataInitializedEventHandler(this.ultraCalendarInfo1_AppointmentDataInitialized);
            this.ultraCalendarInfo1.OwnerDataInitialized += new Infragistics.Win.UltraWinSchedule.OwnerDataInitializedEventHandler(this.ultraCalendarInfo1_OwnerDataInitialized);
            this.ultraCalendarInfo1.AppointmentDataError += new Infragistics.Win.UltraWinSchedule.AppointmentDataErrorEventHandler(this.ultraCalendarInfo1_AppointmentDataError);
            this.ultraCalendarInfo1.OwnerDataError += new Infragistics.Win.UltraWinSchedule.OwnerDataErrorEventHandler(this.ultraCalendarInfo1_OwnerDataError);
            // 
            // ultraDayView1
            // 
            this.ultraDayView1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.ultraDayView1.Location = new System.Drawing.Point(149, 0);
            this.ultraDayView1.Name = "ultraDayView1";
            this.ultraDayView1.Size = new System.Drawing.Size(579, 296);
            this.ultraDayView1.TabIndex = 1;
            this.ultraDayView1.Text = "ultraDayView1";
            // 
            // ultraMonthViewMulti1
            // 
            this.ultraMonthViewMulti1.BackColor = System.Drawing.SystemColors.Window;
            this.ultraMonthViewMulti1.Dock = System.Windows.Forms.DockStyle.Left;
            this.ultraMonthViewMulti1.Location = new System.Drawing.Point(0, 0);
            this.ultraMonthViewMulti1.MonthDimensions = new System.Drawing.Size(1, 2);
            this.ultraMonthViewMulti1.Name = "ultraMonthViewMulti1";
            this.ultraMonthViewMulti1.Size = new System.Drawing.Size(146, 256);
            this.ultraMonthViewMulti1.TabIndex = 2;
            // 
            // splitter2
            // 
            this.splitter2.Location = new System.Drawing.Point(146, 0);
            this.splitter2.Name = "splitter2";
            this.splitter2.Size = new System.Drawing.Size(3, 296);
            this.splitter2.TabIndex = 4;
            this.splitter2.TabStop = false;
            // 
            // AppointmentGrid
            // 
            this.AppointmentGrid.Dock = System.Windows.Forms.DockStyle.Bottom;
            this.AppointmentGrid.Location = new System.Drawing.Point(0, 299);
            this.AppointmentGrid.Name = "AppointmentGrid";
            this.AppointmentGrid.Size = new System.Drawing.Size(728, 128);
            this.AppointmentGrid.TabIndex = 5;
            this.AppointmentGrid.Text = "Appointments Table";
            this.AppointmentGrid.InitializeLayout += new Infragistics.Win.UltraWinGrid.InitializeLayoutEventHandler(this.InitializeLayout);
            this.AppointmentGrid.AfterRowActivate += new System.EventHandler(this.AppointmentGrid_AfterRowActivate);
            // 
            // splitter1
            // 
            this.splitter1.Dock = System.Windows.Forms.DockStyle.Bottom;
            this.splitter1.Location = new System.Drawing.Point(0, 296);
            this.splitter1.Name = "splitter1";
            this.splitter1.Size = new System.Drawing.Size(728, 3);
            this.splitter1.TabIndex = 8;
            this.splitter1.TabStop = false;
            // 
            // splitter3
            // 
            this.splitter3.Dock = System.Windows.Forms.DockStyle.Bottom;
            this.splitter3.Location = new System.Drawing.Point(0, 427);
            this.splitter3.Name = "splitter3";
            this.splitter3.Size = new System.Drawing.Size(728, 3);
            this.splitter3.TabIndex = 10;
            this.splitter3.TabStop = false;
            // 
            // OwnersGrid
            // 
            this.OwnersGrid.Dock = System.Windows.Forms.DockStyle.Bottom;
            this.OwnersGrid.Location = new System.Drawing.Point(0, 430);
            this.OwnersGrid.Name = "OwnersGrid";
            this.OwnersGrid.Size = new System.Drawing.Size(728, 128);
            this.OwnersGrid.TabIndex = 9;
            this.OwnersGrid.Text = "Owners Table";
            this.OwnersGrid.InitializeLayout += new Infragistics.Win.UltraWinGrid.InitializeLayoutEventHandler(this.InitializeLayout);
            this.OwnersGrid.InitializeTemplateAddRow += new Infragistics.Win.UltraWinGrid.InitializeTemplateAddRowEventHandler(this.OwnersGrid_InitializeTemplateAddRow);
            // 
            // OwnersDropDown
            // 
            this.OwnersDropDown.Cursor = System.Windows.Forms.Cursors.Default;
            this.OwnersDropDown.Location = new System.Drawing.Point(448, 320);
            this.OwnersDropDown.Name = "OwnersDropDown";
            this.OwnersDropDown.Size = new System.Drawing.Size(184, 72);
            this.OwnersDropDown.TabIndex = 11;
            this.OwnersDropDown.Text = "ultraDropDown1";
            this.OwnersDropDown.Visible = false;
            // 
            // Form2
            // 
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.ClientSize = new System.Drawing.Size(728, 558);
            this.Controls.Add(this.OwnersDropDown);
            this.Controls.Add(this.ultraDayView1);
            this.Controls.Add(this.splitter2);
            this.Controls.Add(this.ultraMonthViewMulti1);
            this.Controls.Add(this.splitter1);
            this.Controls.Add(this.AppointmentGrid);
            this.Controls.Add(this.splitter3);
            this.Controls.Add(this.OwnersGrid);
            this.Name = "Form2";
            this.Text = "UltraWinSchedule DataBinding";
            this.Load += new System.EventHandler(this.Form2_Load);
            ((System.ComponentModel.ISupportInitialize)(this.ultraDayView1)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.ultraMonthViewMulti1)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.AppointmentGrid)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.OwnersGrid)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.OwnersDropDown)).EndInit();
            this.ResumeLayout(false);

        }
        #endregion

       private const int randomSeed = 0;
        private static Random rnd = new Random(randomSeed);
        private DataSet scheduleData = new DataSet();
        private const int initialAppointmentCount = 200;

        #region Form_Load
        private void Form2_Load(object sender, System.EventArgs e)
        {
            //Create some dummy data
            scheduleData = this.CreateScheduleData();

            //Initialize the schedule controls
            InitializeScheduleProperties();

            //Bind
            this.SetDataBindings();

            //Make some appointments recur
            AddAppointmentRecurrances();

            //Bind the grids so the raw data can be viewed. 
            this.AppointmentGrid.SetDataBinding(this.scheduleData, "Appointments");
            this.OwnersGrid.SetDataBinding(this.scheduleData, "Owners");

            //Set up the Owners DropDown
            this.OwnersDropDown.ValueMember = "Key";
            this.OwnersDropDown.SetDataBinding(this.scheduleData, "Owners");

            //Autosize the grid columns for easier reading. 
            AutoSizeGridColumns(this.AppointmentGrid);
            AutoSizeGridColumns(this.OwnersGrid);
        }
        #endregion Form_Load

        #region Data Creation

        #region Owners
        //An Array of Dummy Owner keys
        private static string[] Owners = new string[]
            {    
                "Andrew", 
                "Bob",
                "Chris", 
                "Donna", 
                "Edward",
                "Felicia",
                "Greg",
                "Harold",
                "Iris",
                "Joe",
                "Kelly",
                "Laura",
                "Mike",
                "Nick",
                "Ophelia",
                "Peter",
                "Quentin",
                "Robert",
                "Sarah",
                "Tara",
                "Uma",
                "Victor",
                "Wendy",
                "Xavier",
                "Yale",
                "Zach",
        };
        #endregion //Owners

        #region CreateAppointmentsDataTable
        //Create the structure of the Appointments Table
        private DataTable CreateAppointmentsDataTable()
        {
            DataTable newTable = new DataTable();

            //Basic Appointment properties
            // In order to function properly, the table must contain data for 
            // Subject, StartDateTime, and EndDateTime. These three fields are 
            // required for an appointment. So all of these will have DefaultValues.
            newTable.Columns.Add("Subject", typeof(string));
            newTable.Columns["Subject"].DefaultValue = "New Appointment";
            newTable.Columns.Add("StartDateTime", typeof(DateTime));
            newTable.Columns["StartDateTime"].DefaultValue = DateTime.Now;
            newTable.Columns.Add("EndDateTime", typeof(DateTime));
            newTable.Columns["EndDateTime"].DefaultValue = DateTime.Now.AddHours(1);
            newTable.Columns.Add("Description", typeof(string));

            // All other fields are Optional.

            //Properties for AllDayEvents
            newTable.Columns.Add("AllDayEvent", typeof(bool));
            newTable.Columns["AllDayEvent"].DefaultValue = false;

            //Properties for Reminders
            newTable.Columns.Add("ReminderEnabled", typeof(bool));
            newTable.Columns["ReminderEnabled"].DefaultValue = false;
            newTable.Columns.Add("ReminderInterval", typeof(int));
            newTable.Columns.Add("ReminderUnits", typeof(int));

            //Properties when using owners
            newTable.Columns.Add("OwnerKey", typeof(string));

            //Properties when using recurring appointments. 
            newTable.Columns.Add("RecurrenceId", typeof(System.Guid));
            newTable.Columns.Add("Recurrence", typeof(Byte[]));
            newTable.Columns.Add("OriginalStartDateTime", typeof(DateTime));

            //DataKey is an extra field that can be used to link the appointment to some external data. 
            newTable.Columns.Add("DataKey", typeof(string));

            //All properties             
            // Any other Appointment properties not covered above are stored as 
            // Binary data in the AllProperties field. This includes properties like 
            // BarColor, Location, etc. 
            newTable.Columns.Add("AllProperties", typeof(Byte[]));

            return newTable;
        }
        #endregion CreateAppointmentsDataTable

        #region CreateOwnersDataTable
        private DataTable CreateOwnersDataTable()
        {
            DataTable newTable = new DataTable();

            //Basic Owner properties
            // In order to function properly, the table must contain data for 
            // the Owners Key. Keys are required for an Owner. 
            newTable.Columns.Add("Key", typeof(string));
            // Normally, we would want the DataTable to enfore unique keys. This
            // line of code is commented out in this example in order to demonstrate
            // the use of the OwnerDataError event.
            //newTable.Columns["Key"].Unique = true;

            //Other Owner properties
            newTable.Columns.Add("Name", typeof(string));
            newTable.Columns.Add("EmailAddress", typeof(string));
            newTable.Columns.Add("Visible", typeof(bool));

            //Unlike Appointments, the Owner properties are all covered by 
            //individual members. But we could save space in the database by storing
            //data as binary using AllProperties and not binding the other fields. 
            newTable.Columns.Add("AllProperties", typeof(Byte[]));
            return newTable;
        }

        #endregion CreateOwnersDataTable

        #region CreateScheduleData
        //Create dummy data
        private DataSet CreateScheduleData()
        {
            DataSet newDataSet = new DataSet();

            DataTable ownersTable = this.CreateOwnersDataTable();
            ownersTable.TableName = "Owners";
            this.CreateOwners(ownersTable);
            newDataSet.Tables.Add(ownersTable);

            DataTable appointmentsTable = this.CreateAppointmentsDataTable();
            appointmentsTable.TableName = "Appointments";
            CreateAppointments(appointmentsTable);
            newDataSet.Tables.Add(appointmentsTable);

            return newDataSet;
        }

        #endregion CreateScheduleData

        #region CreateOwners
        //Create dummy owners
        private void CreateOwners(DataTable ownerTable)
        {
            ownerTable.BeginInit();
            ownerTable.Rows.Clear();
            foreach (string owner in Owners)
                ownerTable.Rows.Add(new object[] { owner, DBNull.Value, DBNull.Value, true });

            ownerTable.AcceptChanges();
            ownerTable.EndInit();
        }
        #endregion CreateOwners

        #region CreateAppointments
        //Create dummy appointments
        private void CreateAppointments(DataTable appointmentTable)
        {
            appointmentTable.BeginInit();

            appointmentTable.Rows.Clear();

            for (int i = 0; i < initialAppointmentCount; i++)
            {
                DataRow newRow = appointmentTable.NewRow();
                newRow["Subject"] = "Appointment " + i.ToString();

                DateTime startTime = DateTime.Now.AddDays(rnd.Next(-10, 10)).AddMinutes(rnd.Next(5, 180));
                newRow["StartDateTime"] = startTime;
                DateTime endTime = startTime.AddMinutes(rnd.Next(5, 180));
                newRow["StartDateTime"] = startTime;
                newRow["EndDateTime"] = endTime;

                int RandomOwnerIndex = rnd.Next(0, Owners.Length - 1);
                newRow["OwnerKey"] = Owners[RandomOwnerIndex];

                appointmentTable.Rows.Add(newRow);
            }

            appointmentTable.AcceptChanges();

            appointmentTable.EndInit();
        }

        #endregion CreateAppointments

        #region AddAppointmentRecurrances
        //Create some recurrances on the appointments to demonstrate that they
        //will be stored in the DataTable
        private void AddAppointmentRecurrances()
        {
            for (int i = 0; i < 10; i++)
            {
                Appointment app = this.ultraCalendarInfo1.Appointments[i];
                app.Recurrence = new AppointmentRecurrence();
                app.Recurrence.PatternFrequency = RecurrencePatternFrequency.Weekly;
                app.Recurrence.RangeLimit = RecurrenceRangeLimit.LimitByNumberOfOccurrences;
                app.Recurrence.RangeMaxOccurrences = 10;
                app.BarColor = Color.Green;
            }
        }
        #endregion AddAppointmentRecurrances

        #endregion Data Creation

        #region Initialization

        #region SetDataBindings
        //Set the DataBindings for Appointments and Owners
        private void SetDataBindings()
        {
            SetAppointmentBindings();
            SetOwnerBindings();
        }
        #endregion SetDataBindings

        #region SetAppointmentBindings
        //Set the Data Bindings for Appointments
        private void SetAppointmentBindings()
        {
            // DataSource & DataMember
            this.ultraCalendarInfo1.DataBindingsForAppointments.SetDataBinding(this.scheduleData, "Appointments");

            // Set the BindingContextControl so the component will use the same context
            // that the grid and any other controls on the form are using. 
            this.ultraCalendarInfo1.DataBindingsForAppointments.BindingContextControl = this;

            // Basic Appointment properties
            this.ultraCalendarInfo1.DataBindingsForAppointments.SubjectMember = "Subject";
            this.ultraCalendarInfo1.DataBindingsForAppointments.DescriptionMember = "Description";

            this.ultraCalendarInfo1.DataBindingsForAppointments.StartDateTimeMember = "StartDateTime";
            this.ultraCalendarInfo1.DataBindingsForAppointments.EndDateTimeMember = "EndDateTime";
            this.ultraCalendarInfo1.DataBindingsForAppointments.AllDayEventMember = "AllDayEvent";

            this.ultraCalendarInfo1.DataBindingsForAppointments.ReminderEnabledMember = "ReminderEnabled";
            this.ultraCalendarInfo1.DataBindingsForAppointments.ReminderIntervalMember = "ReminderInterval";
            this.ultraCalendarInfo1.DataBindingsForAppointments.ReminderUnitsMember = "ReminderUnits";

            //Properties when using owners
            this.ultraCalendarInfo1.DataBindingsForAppointments.OwnerKeyMember = "OwnerKey";

            //Properties when using recurring appointments. 
            this.ultraCalendarInfo1.DataBindingsForAppointments.RecurrenceIdMember = "RecurrenceId";
            this.ultraCalendarInfo1.DataBindingsForAppointments.RecurrenceMember = "Recurrence";
            this.ultraCalendarInfo1.DataBindingsForAppointments.OriginalStartDateTimeMember = "OriginalStartDateTime";

            // All other properties
            this.ultraCalendarInfo1.DataBindingsForAppointments.AllPropertiesMember = "AllProperties";

            //DataKey is an extra field that can be used to link the appointment to some external data. 
            this.ultraCalendarInfo1.DataBindingsForAppointments.DataKeyMember = "DataKey";
        }

        #endregion SetAppointmentBindings

        #region SetOwnerBindings
        //Set the Data Bindings for Owners
        private void SetOwnerBindings()
        {
            // DataSource & DataMember
            this.ultraCalendarInfo1.DataBindingsForOwners.SetDataBinding(this.scheduleData, "Owners");

            // Set the BindingContextControl so the component will use the same context
            // that the grid and any other controls on the form are using. 
            this.ultraCalendarInfo1.DataBindingsForOwners.BindingContextControl = this;

            // Basic Owner properties
            this.ultraCalendarInfo1.DataBindingsForOwners.KeyMember = "Key";
            this.ultraCalendarInfo1.DataBindingsForOwners.NameMember = "Name";
            this.ultraCalendarInfo1.DataBindingsForOwners.EmailAddressMember = "EmailAddress";
            this.ultraCalendarInfo1.DataBindingsForOwners.VisibleMember = "Visible";

            // All other properties
            this.ultraCalendarInfo1.DataBindingsForOwners.AllPropertiesMember = "AllProperties";
        }
        #endregion SetOwnerBindings

        #region InitializeScheduleProperties
        //Initialize some properties on the Schedule controls. 
        private void InitializeScheduleProperties()
        {
            //Hook up he DayView and MonthView to the same CalendarInfo
            this.ultraMonthViewMulti1.CalendarInfo = this.ultraCalendarInfo1;
            this.ultraDayView1.CalendarInfo = this.ultraCalendarInfo1;

            //Allow RecurringAppointmens and Grouping
            this.ultraCalendarInfo1.AllowRecurringAppointments = true;
            this.ultraDayView1.GroupingStyle = DayViewGroupingStyle.DateWithinOwner;
            this.ultraDayView1.ColumnScrolling = DayViewColumnScrolling.ColumnsAcrossGroups;
            this.ultraDayView1.PreferredInViewColumnCount = 6;

            //When you click on a row in the Appointments grid, the appointment is
            //Selected. Make it easier to see by appying a BackColor. 
            this.ultraDayView1.CalendarLook.SelectedAppointmentAppearance.BackColor = SystemColors.Highlight;
        }
        #endregion InitializeScheduleProperties

        #endregion Initialization

        #region Helper methods

        #region AutoSizeGridColumns
        //Autosizes the column in a grid. 
        private void AutoSizeGridColumns(UltraGrid grid)
        {
            foreach (UltraGridBand band in grid.DisplayLayout.Bands)
                foreach (UltraGridColumn column in band.Columns)
                    if (!(column.IsChaptered))
                    {
                        column.PerformAutoResize(PerformAutoSizeType.AllRowsInBand);
                    }
        }
        #endregion AutoSizeGridColumns

        #endregion Helper methods

        #region Grid events

        #region InitializeLayout
        //Handles InitializeLayout for both the AppointmentsGrid and OwnersGrid
        private void InitializeLayout(object sender, Infragistics.Win.UltraWinGrid.InitializeLayoutEventArgs e)
        {
            //Allow adding new rows
            e.Layout.Override.AllowAddNew = AllowAddNew.TemplateOnBottom;

            //Immedaite scrolling
            e.Layout.ScrollStyle = ScrollStyle.Immediate;

            if (sender == this.AppointmentGrid)
            {
                // Set Default Values. These will show up in the TemplateAddRow
                // so it's obvious that the user doesn't have to set them. 
                e.Layout.Bands[0].Columns["Subject"].DefaultCellValue = "New Appointment";
                e.Layout.Bands[0].Columns["StartDateTime"].DefaultCellValue = DateTime.Now;
                e.Layout.Bands[0].Columns["EndDateTime"].DefaultCellValue = DateTime.Now.AddHours(1);
                e.Layout.Bands[0].Columns["ReminderEnabled"].DefaultCellValue = false;
                e.Layout.Bands[0].Columns["AllDayEvent"].DefaultCellValue = false;

                //Use an UltraCalendarCombo for the date fields. It's nicer than
                //UltraDateTimeEditor
                UltraGridColumn dateColumn = e.Layout.Bands[0].Columns["StartDateTime"];
                dateColumn.EditorControl = new UltraCalendarCombo();
                dateColumn.Format = "MM/dd/yyyy hh:mm tt";

                dateColumn = e.Layout.Bands[0].Columns["EndDateTime"];
                dateColumn.EditorControl = new UltraCalendarCombo();
                dateColumn.Format = "MM/dd/yyyy hh:mm tt";

                //Attach the Owners DropDown to the OwnerKey column to allow
                //the user to change an appointment to a new owner. Set the column
                //to DropDownList style, so the user can't enter an invalid owner. 
                e.Layout.Bands[0].Columns["OwnerKey"].Style = Infragistics.Win.UltraWinGrid.ColumnStyle.DropDownList;
                e.Layout.Bands[0].Columns["OwnerKey"].ValueList = this.OwnersDropDown;

            }
        }
        #endregion InitializeLayout

        #region InitializeTemplateAddRow
        int lastOwner = 0;
        private void OwnersGrid_InitializeTemplateAddRow(object sender, Infragistics.Win.UltraWinGrid.InitializeTemplateAddRowEventArgs e)
        {
            //Owner keys need to be unique, so set a default owner key. 
            e.TemplateAddRow.Cells["Key"].Value = "Owner " + lastOwner.ToString();
            lastOwner++;
        }
        #endregion InitializeTemplateAddRow

        #region AfterRowActivate
        private void AppointmentGrid_AfterRowActivate(object sender, System.EventArgs e)
        {
            //Disable painting of the DayView so it doesn't flicker
            this.ultraDayView1.BeginUpdate();

            //Disable the CalendarInfo AfterSelectedAppointmentsChange event to prevent recursion
            this.ultraCalendarInfo1.EventManager.SetEnabled(CalendarInfoEventIds.AfterSelectedAppointmentsChange, false);

            //When a row in the grid is activated, bring the corresponding appointment into view
            //Get the StartTime of the appointment
            DateTime activeStartDateTime = (DateTime)this.AppointmentGrid.ActiveRow.Cells["StartDateTime"].Value;
            //Get the owner of the appointment. If no owner is specified, we use the Unassigned Owner
            string activeOwnerKey = this.AppointmentGrid.ActiveRow.Cells["OwnerKey"].Value.ToString();
            Infragistics.Win.UltraWinSchedule.Owner activeOwner = this.ultraCalendarInfo1.Owners.UnassignedOwner;
            if (activeOwnerKey != "")
                activeOwner = this.ultraCalendarInfo1.Owners[activeOwnerKey];

            //    We only want to do this for non-recurring appointments
            if (this.AppointmentGrid.ActiveRow.Cells["Recurrence"].Value == DBNull.Value)
            {
                //Bring the correct day into view in the DayView by selecting it
                this.ultraCalendarInfo1.SelectedDateRanges.Clear();
                this.ultraCalendarInfo1.SelectedDateRanges.Add(activeStartDateTime, activeStartDateTime);

                //Bring the column into view
                this.ultraDayView1.EnsureColumnInView(activeStartDateTime, activeOwner, false);
                //Bring the TimeSlot into view
                this.ultraDayView1.EnsureTimeSlotVisible(activeStartDateTime, true);

                //Select the Appointment so that it's easier to see. To do this, 
                //we first get all the appointments in a range based on Owner and Date
                this.ultraCalendarInfo1.SelectedAppointments.Clear();
                AppointmentsSubsetCollection apps = this.ultraCalendarInfo1.GetAppointmentsInRange(activeStartDateTime, activeStartDateTime, activeOwner);

                //There could be more than one at the same time, same owner, 
                //so loop through them
                foreach (Appointment app in apps)
                {
                    //Check the BindingListIndex against the ListIndex of the row 
                    //object. This is the Index into the underlying data. Note that 
                    //you cannot use ListObject here because the BindingManager hands 
                    //out two different copies of the object to different controls. 
                    //Also, we have to check if this is an occurence in a recurring 
                    //appointment and if so, use the root appointments BindingListIndex. 
                    if (app.BindingListIndex == this.AppointmentGrid.ActiveRow.ListIndex
                        || (app.RecurringAppointmentRoot != null
                        && app.RecurringAppointmentRoot.BindingListIndex == this.AppointmentGrid.ActiveRow.ListIndex))
                    {
                        //We found the appointment, so select it.
                        this.ultraCalendarInfo1.SelectedAppointments.Add(app);
                    }
                }
            }

            //Re-enable the CalendarInfo AfterSelectedAppointmentsChange event
            this.ultraCalendarInfo1.EventManager.SetEnabled(CalendarInfoEventIds.AfterSelectedAppointmentsChange, true);

            //Re-enable painting of the DayView 
            this.ultraDayView1.EndUpdate();
        }
        #endregion AfterRowActivate

        #endregion Grid events

        #region UltraCalendarInfo Events

        #region DataBinding-related events

        #region OwnerDataError
        private void ultraCalendarInfo1_OwnerDataError(object sender, Infragistics.Win.UltraWinSchedule.OwnerDataErrorEventArgs e)
        {
            if (e.PropertyId == OwnersDataBindingPropertyId.KeyMember)
            {
                //Get the new key
                string newOwnerKey = e.BoundValue.ToString();

                //See if the key already exists in the collection
                if (this.ultraCalendarInfo1.Owners.Exists(newOwnerKey))
                {
                    //Cancel the default message box
                    e.ShowMessageBox = false;

                    //Show a custom error message
                    System.Text.StringBuilder SB = new System.Text.StringBuilder();
                    SB.AppendFormat("There is already an owner with key: {0}\nThis owner in the data source cannot be displayed by UltraWinSchedule.", newOwnerKey);
                    MessageBox.Show(this, SB.ToString(), "Owner cannot be displayed");
                }
            }
        }
        #endregion OwnerDataError

        #region OwnerDataInitialized
        private void ultraCalendarInfo1_OwnerDataInitialized(object sender, Infragistics.Win.UltraWinSchedule.OwnerDataInitializedEventArgs e)
        {
            //If the name has not been set, set it to the same as the key
            //There's no real point to this, but it demonstrates how you can
            //initialize proeprties of the owner
            e.Owner.Visible = true;
            if (e.Owner.Name == null || e.Owner.Name.Length == 0)
            {
                e.Owner.Name = e.Owner.Key;
            }
        }

        #endregion OwnerDataInitialized

        #region AppointmentDataError
        private void ultraCalendarInfo1_AppointmentDataError(object sender, Infragistics.Win.UltraWinSchedule.AppointmentDataErrorEventArgs e)
        {

            //Cancel the default message box
            e.ShowMessageBox = false;

            //Show a custom message box
            DialogResult result = MessageBox.Show(this, "Failed to add appointment. Would you like to set default values?", "Error", MessageBoxButtons.YesNo);
            if (result == DialogResult.Yes)
            {
                //Check it the Subject was null
                DataRow dr = ((DataRowView)e.Appointment.BindingListObject).Row;
                if (dr["Subject"] == DBNull.Value)
                {
                    //Set the subject to a default string
                    e.Appointment.Subject = "Error appointment";
                }

                //Check if the StartDateTime is null
                if (dr["StartDateTime"] == DBNull.Value)
                {
                    //Set StartDateTime to a deafult
                    e.Appointment.StartDateTime = DateTime.Now;
                }

                //Check if the EndDateTime is null and make sure it is after the StartDateTime
                if (dr["EndDateTime"] == DBNull.Value
                    || ((DateTime)dr["EndDateTime"]) <= ((DateTime)dr["StartDateTime"]))
                {
                    //Set EndDateTime to a deafult
                    e.Appointment.EndDateTime = e.Appointment.StartDateTime.AddHours(1);
                }
            }
        }

        #endregion AppointmentDataError

        #region AppointmentDataInitialized
        private void ultraCalendarInfo1_AppointmentDataInitialized(object sender, Infragistics.Win.UltraWinSchedule.AppointmentDataInitializedEventArgs e)
        {
            //Set the BarColor of the appointment to Yellow. 
            //This will differentiate it between recurring appointments (which are 
            //set to green elsewhere) and Appointments which are added through the
            //Schedule controls instead of through the data source. 
            e.Appointment.BarColor = Color.Yellow;
        }
        #endregion AppointmentDataInitialized

        #endregion DataBinding-related events

        #region AfterSelectedAppointmentsChange
        private void ultraCalendarInfo1_AfterSelectedAppointmentsChange(object sender, System.EventArgs e)
        {
            //Select the row in the grid which corresponds to this appointment.
            if (this.ultraCalendarInfo1.SelectedAppointments.Count > 0)
            {
                //Disable the Grid's AfterRowActivate event to prevent recursion
                this.AppointmentGrid.EventManager.SetEnabled(Infragistics.Win.UltraWinGrid.GridEventIds.AfterRowActivate, false);

                int listIndex = -1;

                //If this is a regular (non-recurring) appointment, use it's BindingListIndex. If
                //it's an occurrence of a recurring appointment, use the RecurringAppointmentRoot's
                //BindingListIndex
                if (this.ultraCalendarInfo1.SelectedAppointments[0].RecurringAppointmentRoot == null)
                    listIndex = this.ultraCalendarInfo1.SelectedAppointments[0].BindingListIndex;
                else
                    listIndex = this.ultraCalendarInfo1.SelectedAppointments[0].RecurringAppointmentRoot.BindingListIndex;

                CurrencyManager CM = (CurrencyManager)this.BindingContext[this.scheduleData, "Appointments"];
                CM.Position = listIndex;

                //Re-enable the Grid's AfterRowActivate event 
                this.AppointmentGrid.EventManager.SetEnabled(Infragistics.Win.UltraWinGrid.GridEventIds.AfterRowActivate, true);
            }
        }
        #endregion AfterSelectedAppointmentsChange

        #endregion UltraCalendarInfo Events

    }
}

